package com.gaofei.order.controller;

import com.gaofei.order.service.BusinessMessageSenderService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author : gaofee
 * @date : 14:07 2021/1/19
 * @码云地址 : https://gitee.com/itgaofee
 *
 * 死信队列的演示
 *
 * 死信队列应用场景
 * 通过上面的信息，我们已经知道如何使用死信队列了，
 * 那么死信队列一般在什么场景下使用呢？
 *
 * 一般用在较为重要的业务队列中，确保未被正确消费的消息不被丢弃，
 * 一般发生消费异常可能原因主要有由于消息信息本身存在错误导致处理异常，
 * 处理过程中参数校验异常，或者因网络波动导致的查询异常等等，当发生异常时，
 * 当然不能每次通过日志来获取原消息，然后让运维帮忙重新投递消息（没错，以前就是这么干的= =）。
 * 通过配置死信队列，可以让未正确处理的消息暂存到另一个队列中，待后续排查清楚问题后，
 * 编写相应的处理代码来处理死信消息，这样比手工恢复数据要好太多了。
 *
 * 总结一下死信消息的生命周期：
 *
 * 业务消息被投入业务队列
 * 消费者消费业务队列的消息，由于处理过程中发生异常，于是进行了nck或者reject操作
 * 被nck或reject的消息由RabbitMQ投递到死信交换机中
 * 死信交换机将消息投入相应的死信队列
 * 死信队列的消费者消费死信消息
 * 死信消息是RabbitMQ为我们做的一层保证，其实我们也可以不使用死信队列，而是在消息消费异常时，
 * 将消息主动投递到另一个交换机中，当你明白了这些之后，这些Exchange和Queue想怎样配合就能怎么配合。
 * 比如从死信队列拉取消息，然后发送邮件、短信、钉钉通知来通知开发人员关注。
 * 或者将消息重新投递到一个队列然后设置过期时间，来进行延时消费。
 *
 *
 *那么什么时候需要用延时队列呢？考虑一下以下场景：
 *
 * 订单在十分钟之内未支付则自动取消。
 * 新创建的店铺，如果在十天内都没有上传过商品，则自动发送消息提醒。
 * 账单在一周内未支付，则自动结算。
 * 用户注册成功后，如果三天内没有登陆则进行短信提醒。
 * 用户发起退款，如果三天内没有得到处理则通知相关运营人员。
 * 预定会议后，需要在预定的时间点前十分钟通知各个与会人员参加会议。
 *
 */
@RestController
@RequestMapping("rabbitmq")
public class RabbitMQMsgController {

    @Autowired
    private BusinessMessageSenderService sender;

    @Autowired
    private RabbitTemplate template;


    @RequestMapping("msgConfirm")

    @Transactional(rollbackFor = Exception.class,transactionManager = "rabbitTransactionManager")
    public void msgConfirm(String msg){
        template.convertAndSend("msgExchange","","你好,这是我刚刚发送的消息!!");
    }

    @RequestMapping("sendmsg")
    public void sendMsg(String msg){
        sender.sendMsg(msg);
    }
}
